package com.tao.anr

import android.os.Debug
import android.os.Handler
import android.os.Looper
import android.util.Log

/**
 *reate by tao on{DATE}
 */
class ANRDog : Runnable, WaitTaskManager.WaitAnrCall {
    private var build: Build
    val tag = javaClass.simpleName
    val checkHandler = Handler(Looper.getMainLooper())
    var checkTherad: Thread? = null
    var rinIng = false

    private constructor(build: Build) {
        this.build = build
    }

    fun start() {
        if (rinIng) return
        Thread(this).start()
    }

    var stop = false
    fun stop() {
        if (!rinIng) return
        stop = true
        checkHandler.removeCallbacksAndMessages(null)
        checkTherad?.let {
            it.interrupt()
            checkTherad = null
        }
        WaitTaskManager.manager.stop()
    }


    override fun run() {
        checkTherad = Thread.currentThread()
        try {
            checkTherad?.let {
                rinIng = true
                while (!it.isInterrupted && !stop) {
                    try {
                        Thread.sleep(build.anrCheckTime)
                    } catch (e: Exception) {
                    }
                    if (anrIng){
                        checkHandler.post(MainTask())
                    }else {
                        WaitTaskManager.manager.inrunOnWaitTask(
                            AnrInfo(
                                System.currentTimeMillis(),
                                0,
                                false
                            ), build.anrTimeOut, this
                        )
                    }
                }
            }
        } catch (e: Exception) {
        } finally {
            rinIng = false
        }
    }

    /**
     * 检测当前ui线程是否恢复
     */
   inner class MainTask : Runnable {
        override fun run() {
            anrIng =false
        }
    }

    /**
     * 得到UI线程消息
     */
    private fun onMsg(anrInfo: AnrInfo) {
//        Log.e(tag, "onMsg $anrInfo")
    }

    override fun onWaitStart(anrInfo: AnrInfo) {
        if (stop || !rinIng) return
//        Log.e(tag, "post $anrInfo")
        checkHandler.postDelayed(MsgTask(this, anrInfo), 20)
    }

    override fun onWait(anrInfo: AnrInfo) {
        if (stop || !rinIng) return
//        Log.e(tag, "onWait $anrInfo")
        if (anrInfo.isAnr) {
            onAnr(anrInfo)
        }
    }

    var anrIng =false
    private fun onAnr(anrInfo: AnrInfo) {
//        Log.e(tag, "onAnr $anrInfo")
        WaitTaskManager.manager.stop()

        var error: ANRError? = null
        build.namePrefix?.let {
            error = ANRError.New(anrInfo.endTimeOut - anrInfo.startTime, it, true)

        } ?: let {
            error = ANRError.NewMainOnly(anrInfo.endTimeOut - anrInfo.startTime)
        }
        anrInfo.error = error

        if (build.ignoreDebugger && (Debug.isDebuggerConnected() || Debug.waitingForDebugger())) {
//            Log.e(tag, " ANR_忽略调试模式 ")
            build.anrListener?.let { it.onIgnore(anrInfo) }
            return
        }
        build.anrInterceptor?.let {
            if (it.intercept(anrInfo)) return
        }
        
        build.anrListener?.let {
            it.onAnr(anrInfo)
        }
        anrIng =true
        
    }

    class MsgTask(val anrDog: ANRDog, val lock: AnrInfo) : Runnable {

        override fun run() {
            anrDog.onMsg(lock)
            synchronized(lock) {
                lock.notifyAll()
            }
        }
    }


    class Build {

        // anr触发时间
        var anrTimeOut = 5000L

        // anr检测时间
        var anrCheckTime = 1000L

        var ignoreDebugger = true
        var anrListener: ANRListener? = null
 
        
        var anrInterceptor: ANRInterceptor? = null
        var namePrefix: String? = ""

        fun build(): ANRDog {
            return ANRDog(this)
        }
    }


}